package com.csw.android.dev_utils.log

import android.app.Activity
import android.app.Application
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.util.Log
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.csw.android.dev_utils.R
import com.csw.android.dev_utils.SDK
import com.csw.android.dev_utils.ex.DEBUG
import com.csw.android.dev_utils.log.request.RequestLogInfo
import com.csw.android.dev_utils.utils.RxBus

class LogDisplayController private constructor() {

    companion object {
        const val MAX_LOG_SIZE = 100

        //单例
        val instance = LogDisplayController()

        object AddLogBroadcast {
            const val ACTION = "ADD_LOG"
            const val KEY_LOG_TAG = "logTag:String"
            const val KEY_LOG_MESSAGE = "message:String?"
            const val KEY_LOG_LEVEL = "level:Int?"
            const val KEY_LOG_REQUEST_HEADER = "requestHeader:String?"
            const val KEY_LOG_REQUEST = "request:String?"
            const val KEY_LOG_RESPONSE = "response:String?"
        }

    }

    //是否展开日志，默认false
    var logExpanded: Boolean = false
        private set
    private var cursor = 0
    private val logArray = Array<LogInfo?>(MAX_LOG_SIZE) {
        null
    }
    private val callback = object : Application.ActivityLifecycleCallbacks {

        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
            activity.window?.decorView?.run {
                if (this is ViewGroup) {
                    //添加View
                    val fragmentContainer =
                        findViewById<FrameLayout>(R.id.dev_utils_fragment_container)
                    if (fragmentContainer == null) {
                        val fc = FrameLayout(activity)
                        fc.id = R.id.dev_utils_fragment_container
                        addView(
                            fc, ViewGroup.LayoutParams(
                                ViewGroup.LayoutParams.MATCH_PARENT,
                                ViewGroup.LayoutParams.MATCH_PARENT
                            )
                        )
                    }
                    //添加fragment
                    if (activity is AppCompatActivity) {
                        activity.supportFragmentManager.beginTransaction()
                            .replace(R.id.dev_utils_fragment_container, LogViewFragment())
                            .commitAllowingStateLoss()
                    }
                }
            }
        }

        override fun onActivityStarted(activity: Activity) {
        }

        override fun onActivityResumed(activity: Activity) {
        }

        override fun onActivityPaused(activity: Activity) {
        }

        override fun onActivityStopped(activity: Activity) {
        }

        override fun onActivityDestroyed(activity: Activity) {
        }

        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
        }
    }

    private val broadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            intent ?: return
            when (intent.action) {
                AddLogBroadcast.ACTION -> {
                    val tag = intent.getStringExtra(AddLogBroadcast.KEY_LOG_TAG) ?: return
                    val message = intent.getStringExtra(AddLogBroadcast.KEY_LOG_MESSAGE)
                    addLog(RequestLogInfo(
                        Log.ERROR, System.currentTimeMillis(), tag, message.orEmpty()
                    ).apply {
                        level1.postValue(
                            intent.getIntExtra(
                                AddLogBroadcast.KEY_LOG_LEVEL, Log.ERROR
                            )
                        )
                        requestHeader.postValue(intent.getStringExtra(AddLogBroadcast.KEY_LOG_REQUEST_HEADER))
                        request.postValue(intent.getStringExtra(AddLogBroadcast.KEY_LOG_REQUEST))
                        response.postValue(intent.getStringExtra(AddLogBroadcast.KEY_LOG_RESPONSE))
                    })
                }
            }
        }
    }

    fun init(application: Application) {
        if (!SDK.getApplication().DEBUG) {
            return
        }
        application.registerActivityLifecycleCallbacks(callback)
        LocalBroadcastManager.getInstance(application).registerReceiver(
            broadcastReceiver, IntentFilter(AddLogBroadcast.ACTION)
        )
    }

    fun addLog(logInfo: LogInfo) {
        if (!SDK.getApplication().DEBUG) {
            return
        }
        cursor = (cursor + 1) % MAX_LOG_SIZE
        logArray[cursor] = logInfo
        RxBus.getDefault().post(OnNewLogInfo(logInfo))
    }

    fun getLogList(): ArrayList<LogInfo> {
        val result = ArrayList<LogInfo>(MAX_LOG_SIZE)
        for (i in (cursor + 1)..(cursor + MAX_LOG_SIZE)) {
            logArray[i % MAX_LOG_SIZE]?.run {
                result.add(this)
            }
        }
        return result
    }

    fun onLogExpandChanged(expand: Boolean) {
        logExpanded = expand
        RxBus.getDefault().post(OnLogExpandChanged(expand))
    }

}